<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <title>Document</title>
  </head>

  <body></body>
  <script>
    //<% 和 %> 之间可以放置任意的 JavaScript 代码
    //<%= 和 %> 之间执行任意的 JavaScript 表达式并且输出在模版上
    //传入的 data 可以作为模版引擎执行的上下文进行数据的引用
    const templateStr = `
    <ul class="users">
      <% users.forEach((user) => { %>
        <li class="user-item">
          <%= 'My name is ' + user.name %>
          <%= 'My age is ' + user.age %>
        </li>
      <% }) %>
    </ul>
    `;

    const data = {
      users: [
        { name: "Jerry", age: 12 },
        { name: "Lucy", age: 13 },
        { name: "Tomy", age: 14 }
      ]
    };

    let hm = render(templateStr, data);
    document.getElementsByTagName("body")[0].innerHTML = hm;

    function render(template, data) {
      const reg_1 = /<%[^=](.*?)%>/g; //匹配JavaScript 代码
      const reg_2 = /<%=(.*?)%>/g; //匹配JavaScript 表达式
      let code_str = [];
      let match;
      let cursor = 0;

      code_str.push("const list = [];\r\n");
      // code_str.push("const users = arguments[0];\r\n");
      // code_str.push("console.log(arguments);\r\n");

      while ((match = reg_1.exec(template))) {
        code_str.push(
          `list.push(\`${template.slice(cursor, match.index)}\`);\r\n`
        );
        code_str.push(`${match[1]}\r\n`);
        cursor = match.index + match[0].length; //起始点 = 找到的字符开始下标 + 字符的长度
      }
      code_str.push(`list.push(\`${template.slice(cursor)}\`);\r\n`);
      code_str = code_str.join("").replace(reg_2, ($1, match) => {
        return "${" + match + "}";
      });
      code_str += "return list.join('')";
      return new Function(`with(this){${code_str}}`).call(data);
    }
  </script>
</html>
